﻿/*  
 * Helix Engine
 * http://helixengine.codeplex.com/
 * 
 * Copyright (c) 2010 - 2011 Joe Hegarty
 *  
 * This source code is subject to the terms of the Microsoft Public License (Ms-PL). 
 *  
 * Redistribution and use in source and binary forms, with or without modification, 
 * is permitted provided that redistributions of the source code retain the above 
 * copyright notices and this file header. 
 * 
 * For details please see http://www.opensource.org/licenses/ms-pl.html 
 *  
 * All other rights reserved. 
 *
 */  


using System;
using System.Windows.Media.Imaging;

using HelixEngine;
using HelixEngine.Maths;
using HelixEngine.Resources;
using HelixEngine.Render;

namespace HelixGame.World.Entities.Components
{
    /// <summary>
    /// 
    /// </summary>
    public class FloorComponent : EntityComponent
    {
        ResourcePackage _tilePackage;
        State _state = State.Idle;

        int _floorWidth = 18;
        int _floorHeight = 10;
        int _floorTileStyle = 1;

        enum State
        {
            WaitingForPackage,
            DrawFloor,
            WriteFloor,
            Idle
        }

        /// <summary>
        /// 
        /// </summary>
        public int Width
        {
            get { return _floorWidth;  }
        }

        /// <summary>
        /// 
        /// </summary>
        public int Height
        {
            get { return _floorHeight; }
        }

        /// <summary>
        /// 
        /// </summary>
        public override void OnInitialised()
        {
            Parent.AddEC<GraphicAppearenceComponent>();
            GraphicAppearenceComponent graphicAppearance = null;

            if (Parent.GetEC(ref graphicAppearance))
            {
                Parent.AddComponentNeedingUpdate(this);
                
                _tilePackage = Engine.Get().ResourceManager.FetchPackage("room");
                _state = State.WaitingForPackage;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public override void OnCleanup()
        {
            Parent.RemoveComponentNeedingUpdate(this);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="time"></param>
        public override void Update(EngineTime time)
        {
            switch(_state)
            {
                case State.WaitingForPackage:
                    UpdateWaitingForPackage();
                    break;

                case State.DrawFloor:
                    UpdateDrawFloor();
                    break;

                case State.WriteFloor:
                    UpdateWriteFloor();
                    break;


            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="point"></param>
        /// <returns></returns>
        public bool IsTileValid(IsometricPoint point)
        {
            return ((point.X >= 0 && point.X < _floorWidth) &&
                    (point.Y >= 0 && point.Y < _floorHeight));
        }

        void UpdateWaitingForPackage()
        {
            if (_tilePackage.IsComplete)
            {
                _state = State.DrawFloor;
            }
        }

        void UpdateDrawFloor()
        {
            GraphicAppearenceComponent graphicAppearance = null;

            if (Parent.GetEC(ref graphicAppearance))
            {
                string tilePath = "tiles/" + _floorTileStyle.ToString() + ".png";
                WriteableBitmap tile = _tilePackage.GetBitmap(tilePath);

                graphicAppearance.CreateNewTargetScene("Floor");

                for (int x = 0; x < _floorWidth; ++x)
                {
                    for (int y = 0; y < _floorHeight; ++y)
                    {
                        IsometricPoint tilePoint = new IsometricPoint(x, y);
                        Vector2 targetPos = IsometricHelper.WorldSpaceToScreenSpace(tilePoint);
                        int zindex = IsometricHelper.CalculateTileDepth(tilePoint);
                        graphicAppearance.QueueWrite(zindex, tile, targetPos);
                    }
                }

                graphicAppearance.Render();

                _state = State.WriteFloor;

            }
            else
            {
                _state = State.Idle;
            }
        }

        void UpdateWriteFloor()
        {
             GraphicAppearenceComponent graphicAppearance = null;

             if (Parent.GetEC(ref graphicAppearance))
             {
                 graphicAppearance.QueueToRootScene(WriteableBitmapExtensions.BlendMode.None);
             }
             else
             {
                 _state = State.Idle;
             }
        }

    }
}
